package com.lunesu.bjair;

import java.io.BufferedReader;
import java.io.IOException;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;

/**
 * @author Lionello
 * 
 */
public class BeijingAirAppWidgetProvider extends android.appwidget.AppWidgetProvider {

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		final int N = appWidgetIds.length;
		
		// Create an Intent to launch BeijingAirActivity
		Intent intent = new Intent(context, BeijingAirActivity.class);
		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

		// Perform this loop procedure for each App Widget that belongs to this provider
		for (int i=0; i<N; i++) {
			int appWidgetId = appWidgetIds[i];
						
			// Get the layout for the App Widget and attach an on-click listener to the button
			RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.bjair_button);
			views.setOnClickPendingIntent(R.id.button1, pendingIntent);
			
			// Tell the AppWidgetManager to perform an update on the current App Widget
			appWidgetManager.updateAppWidget(appWidgetId, views);
		}
		
		//context.startService(new Intent(context, BeijingAirUpdateService.class));
		refresh(context);
	}
	
	private void refresh(final Context context) {
		
		new Thread() { 
			@Override
			public void run() {
				String url = context.getString(R.string.bjair_url);
				// Get the air quality from HTTP (not interested in the rest of the page)
			    int airquality = BeijingAirAppWidgetProvider.getAirQuality(url, null);
				// Update the app-widget
				updateWidget(context, airquality);
			}
		}.start();
	}

	/** Update the text and/or image of the app-widget.
	 * @param context the Context to use for updating this widget.
	 * @param airquality the air quality index, as retrieved by getAirQuality.
	 */
	public static void updateWidget(Context context, int airquality) {
		RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.bjair_button);
		if (airquality >= 0) {
			// update the views in the layout (text + icon)
			updateViews.setImageViewResource(R.id.airqualityicon, getDrawableId(airquality));
			updateViews.setTextViewText(R.id.airqualitytext, ((Integer)airquality).toString());
		}
		else {
			updateViews.setTextViewText(R.id.airqualitytext, context.getText(R.string.widget_error));
		}

		// When the user presses the button we launch our activity
		Intent activityintent = new Intent(context, BeijingAirActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, activityintent, 0);	
        updateViews.setOnClickPendingIntent(R.id.button1, pendingIntent);

		// Push update for this widget to the home screen
		ComponentName thisWidget = new ComponentName(context, BeijingAirAppWidgetProvider.class);
		AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
		appWidgetManager.updateAppWidget(thisWidget, updateViews);
	}
	
	/** Get the resource ID of the drawable for a certain AQI level.
	 * @param level the air quality index, between 0 and 500/
	 * @return the resource ID of the drawable for this AQI level.
	 */
	private static int getDrawableId(int level) {
		if (level > 300)
			return R.drawable.brown;
		if (level > 200)
			return R.drawable.purple;
		if (level > 150)
			return R.drawable.red;
		if (level > 100)
			return R.drawable.orange;
		if (level > 50)
			return R.drawable.yellow;
		else
			return R.drawable.green;
	}

	/** Check whether the input string contains the AQI level.
	 * @param s a line of HTML from HTTP
	 * @return the parsed air quality index, or -1 if none was found.
	 */
	private static int parseAirQuality(String s) {
		// FAST: check for the field with id 'number'
		int i = s.indexOf("id=\"number\">");
		if (i >= 0) { 
			// parse the number
			s = s.substring(i+12, i+15).trim();
			i = Integer.parseInt(s);
		}
		return i;
	}
	
	/** Retrieve the latest air quality index from the specified site.
	 * @param url the URL of the site with the AQI information
	 * @param sb a StringBuilder instance that will receive the entire HTML page
	 * @return the air quality index, as parsed from the HTML
	 * @throws IOException in case an HTTP error occurs
	 */
	public static int getAirQuality(String url, StringBuilder sb) {
		int airquality = -1;
		try {
			final BufferedReader str = HttpHelpers.openUrl(url);
			try {
				// TODO: use content-length header to preallocate string buffer
				int maxline = 1000; //prevent inf loops
				while (--maxline > 0) {
					String s = str.readLine();
					if (s == null)
						break;
					if (airquality < 0) {
						airquality = parseAirQuality(s);
						// early out, if we don't need the whole response
						if (airquality >= 0 && sb == null)
							break;
					}
					if (sb != null)
						sb.append(s);
				}
			}
			finally {
				str.close();
			}
		} 
		catch (IOException e) {
			//Log.e("error", "BeijingAirActivity.onStart", e);
			// ignore what we've read so far
			if (sb != null)
				sb.setLength(0);
		} 
		catch (NumberFormatException e) {
			// The webpage was changed? 
		}
		return airquality;
	}

}
